package com.demo.sender.notice.lark;

import com.alibaba.fastjson2.JSON;
import com.demo.common.ResultData;
import com.demo.request.NoticeBaseReq;
import com.demo.sender.notice.NoticeSenderService;
import com.demo.sender.notice.lark.enums.LarkTypeEnum;
import com.demo.sender.notice.lark.request.LarkMessageReq;
import com.demo.sender.notice.lark.response.LarkResult;
import com.demo.sender.notice.lark.util.LarkSignUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * 文档地址：<a href="https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot">https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot</a>
 *
 * @author wangfengchen
 */
@Slf4j
@Component
public class LarkSender implements NoticeSenderService {


  @Autowired
  private RestTemplate restTemplate;


  @Override
  public ResultData<Object> send(NoticeBaseReq req) {
    LarkTypeEnum typeEnum = LarkTypeEnum.match(req.getMsgType());
    if (ObjectUtils.isEmpty(typeEnum)) {
      return ResultData.fail("消息类型错误");
    }
    LarkMessageReq larkMessageReq = new LarkMessageReq();
    larkMessageReq.setMsg_type(req.getMsgType());
    if (StringUtils.isNotBlank(req.getSecret())) {
      int timestamp = (int) (System.currentTimeMillis() / 1000L);
      String sign = LarkSignUtil.genSign(req.getSecret(), timestamp);
      larkMessageReq.setSign(sign);
      larkMessageReq.setTimestamp(timestamp);
    }
    // 判断发送消息类型
    if (typeEnum == LarkTypeEnum.INTERACTIVE) {
      larkMessageReq.setCard(req.getContent());
      return send(req.getWebhook(), larkMessageReq);
    }
    larkMessageReq.setContent(req.getContent());
    return send(req.getWebhook(), larkMessageReq);
  }

  /**
   * 消息发送
   *
   * @param webhook
   * @param req
   * @return
   */
  private ResultData<Object> send(String webhook, LarkMessageReq req) {
    String botUrl = "https://open.larksuite.com/open-apis/bot/v2/hook/%s";
    String url = String.format(botUrl, webhook);
    log.info("lark消息发送，url = {}，request = {}", url, JSON.toJSONString(req));
    ResponseEntity<LarkResult> respEntity = this.restTemplate.postForEntity(url, req, LarkResult.class);
    log.info("lark消息发送，respEntity = {}", JSON.toJSONString(respEntity));
    if (ObjectUtils.isEmpty(respEntity)) {
      log.warn("lark消息发送失败");
      return ResultData.fail(501, "lark消息发送异常,直接返回");
    }
    if (respEntity.getStatusCode().value() != HttpStatus.OK.value() || respEntity.getBody() == null) {
      return ResultData.fail(respEntity.getStatusCodeValue(), respEntity.toString());
    }
    LarkResult result = respEntity.getBody();
    log.info("result = {} ", result);
    int code = result.getCode();
    if (code != 0) {
      String message = result.getMsg();
      switch (code) {
        case 19021:
          message = "签名校验失败，请排查以下原因：时间戳距发送时已超过 1 小时，签名已过期";
          break;
        case 19022:
          message = "群机器人开启IP地址限制，请返回确认";
        case 19024:
          message = "群机器人关键词校验失败，请返回确认";
          break;
        default:
          break;
      }
      log.error("lark消息发送失败, result = {} ", result);
      return ResultData.fail(code, message);
    } else {
      return ResultData.success();
    }
  }


}
